/**
 * XDevice 简化API使用示例
 * 
 * 展示类POSIX接口的使用方法，使用逻辑设备名而非文件路径
 * 
 * 重要：设备必须在配置文件中预定义，不能运行时动态创建
 */

#include <libxdevice.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* 示例1: 基本设备操作 */
int basic_device_operations() {
    printf("=== 基本设备操作示例 ===\n");
    
    // 初始化XDevice库 - 这会创建配置文件中预定义的所有设备
    int ret = xdevice_init("/etc/xdevice/cluster.conf");
    if (ret != XDEVICE_OK) {
        fprintf(stderr, "Failed to initialize XDevice: %s\n", xdevice_strerror(ret));
        return -1;
    }
    
    printf("XDevice initialized successfully (version %s)\n", xdevice_version());
    
    // 打开预定义的设备（必须在配置文件中定义）
    xdevice_fd_t fd = xdevice_open("database", XDEVICE_O_RDWR, 0);
    if (!XDEVICE_FD_VALID(fd)) {
        fprintf(stderr, "Failed to open device 'database': %s\n", xdevice_strerror(fd));
        fprintf(stderr, "Please ensure 'database' device is defined in cluster.conf\n");
        xdevice_cleanup();
        return -1;
    }
    
    printf("Device 'database' opened successfully, fd=%d\n", fd);
    
    // 写入数据
    const char* test_data = "Hello, XDevice distributed storage!";
    ssize_t written = xdevice_pwrite(fd, test_data, strlen(test_data), 0);
    if (XDEVICE_FAILED(written)) {
        fprintf(stderr, "Write failed: %s\n", xdevice_strerror(written));
        xdevice_close(fd);
        xdevice_cleanup();
        return -1;
    }
    
    printf("Written %zd bytes\n", written);
    
    // 同步数据(确保跨节点复制完成)
    ret = xdevice_fsync(fd);
    if (ret != XDEVICE_OK) {
        fprintf(stderr, "Sync failed: %s\n", xdevice_strerror(ret));
    } else {
        printf("Data synchronized across cluster\n");
    }
    
    // 读取数据验证
    char read_buffer[256];
    ssize_t read_bytes = xdevice_pread(fd, read_buffer, sizeof(read_buffer) - 1, 0);
    if (XDEVICE_FAILED(read_bytes)) {
        fprintf(stderr, "Read failed: %s\n", xdevice_strerror(read_bytes));
    } else {
        read_buffer[read_bytes] = '\0';
        printf("Read %zd bytes: '%s'\n", read_bytes, read_buffer);
    }
    
    // 获取设备属性
    xdevice_stat_t stat;
    if (xdevice_fstat(fd, &stat) == XDEVICE_OK) {
        printf("Device info:\n");
        printf("  Name: %s\n", stat.name);
        printf("  Size: %lu bytes\n", stat.size);
        printf("  Block size: %u\n", stat.blksize);
        printf("  Replicas: %d (healthy: %d)\n", stat.replicas, stat.healthy_replicas);
        printf("  Created: %s", ctime(&stat.ctime));
    }
    
    // 关闭设备
    xdevice_close(fd);
    printf("Device closed\n");
    
    // 清理库
    xdevice_cleanup();
    printf("XDevice cleanup completed\n");
    
    return 0;
}

/* 示例2: 应用程序数据库设备操作 */
int database_device_example() {
    printf("\n=== 数据库设备操作示例 ===\n");
    
    if (xdevice_init(NULL) != XDEVICE_OK) {  // 使用默认配置
        return -1;
    }
    
    // 打开预定义的数据库设备（必须在配置文件中定义）
    xdevice_fd_t db_fd = xdevice_open("database", XDEVICE_O_RDWR, 0);
    if (!XDEVICE_FD_VALID(db_fd)) {
        fprintf(stderr, "Failed to open database device: %s\n", xdevice_strerror(db_fd));
        fprintf(stderr, "Please ensure 'database' device is defined in cluster.conf\n");
        xdevice_cleanup();
        return -1;
    }
    
    printf("Database device opened successfully\n");
    
    // 模拟数据库页面写入
    const size_t page_size = 4096;
    char page_data[page_size];
    
    for (int page = 0; page < 10; page++) {
        // 准备页面数据
        snprintf(page_data, sizeof(page_data), 
                "Database page %d with transaction data...", page);
        
        // 写入页面
        off_t offset = page * page_size;
        ssize_t written = xdevice_pwrite(db_fd, page_data, page_size, offset);
        if (XDEVICE_FAILED(written)) {
            fprintf(stderr, "Failed to write page %d: %s\n", 
                   page, xdevice_strerror(written));
            break;
        }
        
        // 每写入几个页面就同步一次(模拟事务提交)
        if (page % 3 == 2) {
            xdevice_fsync(db_fd);
            printf("Transaction committed (pages 0-%d)\n", page);
        }
    }
    
    xdevice_close(db_fd);
    xdevice_cleanup();
    return 0;
}

/* 示例3: 错误处理和健康检查 */
int error_handling_example() {
    printf("\n=== 错误处理和健康检查示例 ===\n");
    
    // 检查健康状态
    xdevice_health_t health;
    int health_status = xdevice_health_check(&health);
    
    if (health_status > 0) {
        printf("Cluster is healthy:\n");
        printf("  Nodes: %d active / %d total\n", 
               health.active_nodes, health.total_nodes);
        printf("  Availability: %.1f%%\n", health.availability * 100);
        printf("  Has leader: %s\n", health.has_leader ? "Yes" : "No");
    } else if (health_status == 0) {
        printf("Cluster is unhealthy - some operations may fail\n");
    } else {
        printf("Cannot check cluster health: %s\n", xdevice_strerror(health_status));
    }
    
    if (xdevice_init(NULL) != XDEVICE_OK) {
        return -1;
    }
    
    // 尝试访问不存在的设备
    xdevice_fd_t fd = xdevice_open("nonexistent_device", XDEVICE_O_RDONLY, 0);
    if (!XDEVICE_FD_VALID(fd)) {
        printf("Expected error for nonexistent device: %s\n", xdevice_strerror(fd));
    }
    
    // 尝试打开不存在的设备（应该失败）
    xdevice_fd_t fd1 = xdevice_open("database", XDEVICE_O_RDWR, 0);
    if (XDEVICE_FD_VALID(fd1)) {
        // 尝试以独占模式打开同一设备（应该失败）
        xdevice_fd_t fd2 = xdevice_open("database", XDEVICE_O_EXCL | XDEVICE_O_RDWR, 0);
        if (!XDEVICE_FD_VALID(fd2)) {
            printf("Expected error for exclusive open: %s\n", xdevice_strerror(fd2));
        }
        xdevice_close(fd1);
    }
    
    xdevice_cleanup();
    return 0;
}

/* 示例4: WAL(Write-Ahead Log)应用场景 */
int wal_application_example() {
    printf("\n=== WAL应用场景示例 ===\n");
    
    if (xdevice_init(NULL) != XDEVICE_OK) {
        return -1;
    }
    
    // 打开预定义的WAL设备（必须在配置文件中定义）
    xdevice_fd_t wal_fd = xdevice_open("logs", XDEVICE_O_RDWR, 0);
    if (!XDEVICE_FD_VALID(wal_fd)) {
        fprintf(stderr, "Failed to open WAL device 'logs': %s\n", xdevice_strerror(wal_fd));
        fprintf(stderr, "Please ensure 'logs' device is defined in cluster.conf\n");
        xdevice_cleanup();
        return -1;
    }
    
    printf("WAL device opened successfully\n");
    
    // 模拟应用程序事务日志写入
    off_t wal_offset = 0;
    
    for (int tx = 1; tx <= 100; tx++) {
        char log_entry[512];
        int entry_size = snprintf(log_entry, sizeof(log_entry),
                                 "TXN-%06d: BEGIN -> UPDATE table SET value=%d -> COMMIT\n",
                                 tx, tx * 100);
        
        // 写入WAL条目
        ssize_t written = xdevice_pwrite(wal_fd, log_entry, entry_size, wal_offset);
        if (XDEVICE_FAILED(written)) {
            fprintf(stderr, "WAL write failed for transaction %d\n", tx);
            break;
        }
        
        wal_offset += written;
        
        // WAL设备的数据会自动同步到集群
        if (tx % 10 == 0) {
            printf("Processed %d transactions, WAL size: %ld bytes\n", tx, wal_offset);
        }
    }
    
    printf("WAL operations completed\n");
    
    xdevice_close(wal_fd);
    xdevice_cleanup();
    return 0;
}

/* 示例5: 设备列表和管理 */
int device_management_example() {
    printf("\n=== 设备列表和管理示例 ===\n");
    
    if (xdevice_init(NULL) != XDEVICE_OK) {
        return -1;
    }
    
    // 列出所有设备（从配置文件中预定义的设备）
    printf("Listing all predefined devices...\n");
    char devices[100][256];
    int count = xdevice_list_devices(devices, 100);
    
    if (count > 0) {
        printf("Found %d predefined devices in cluster:\n", count);
        
        for (int i = 0; i < count; i++) {
            printf("\nDevice: %s\n", devices[i]);
            
            // 打开设备获取详细信息
            xdevice_fd_t fd = xdevice_open(devices[i], XDEVICE_O_RDONLY, 0);
            if (XDEVICE_FD_VALID(fd)) {
                xdevice_stat_t stat;
                if (xdevice_fstat(fd, &stat) == XDEVICE_OK) {
                    printf("  Size: %lu bytes (%.2f MB)\n", 
                           stat.size, stat.size / (1024.0 * 1024.0));
                    printf("  Blocks: %lu x %u bytes\n", 
                           stat.blocks, stat.blksize);
                    printf("  Replicas: %d healthy / %d total\n",
                           stat.healthy_replicas, stat.replicas);
                    printf("  Created: %s", ctime(&stat.ctime));
                    printf("  Modified: %s", ctime(&stat.mtime));
                }
                xdevice_close(fd);
            }
        }
    } else if (count == 0) {
        printf("No devices found in cluster\n");
    } else {
        printf("Error listing devices: %s\n", xdevice_strerror(count));
    }
    
    xdevice_cleanup();
    return 0;
}

int main() {
    printf("XDevice 简化API使用示例\n");
    printf("========================\n");
    
    // 运行各种示例
    basic_device_operations();
    database_device_example();
    error_handling_example();
    wal_application_example();
    device_management_example();
    
    printf("\n所有示例执行完成！\n");
    printf("XDevice提供了类似POSIX的简洁接口，\n");
    printf("使用逻辑设备名而非文件路径，\n");
    printf("隐藏了分布式存储的复杂性，\n");
    printf("为应用程序提供透明的数据可靠性保障。\n");
    
    return 0;
}
